#!/usr/bin/env python

import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.api.labs import taskqueue
from schema import *

import logging

class RankInitializer(webapp.RequestHandler):
  def post(self):
    PAGESIZE = 1
    next = None
    computationid = long(self.request.get("computationid"))
    logging.debug("I'll count nodes for computation %i." % computationid)
    computation = RankComputation.get_by_id(computationid)
    logging.debug("The computation key is %s." % str(computation.key()))
    bookmark = self.request.get("node_key")
    logging.debug("The node key is %s." % bookmark)
    
    nodes = LinkGraphNode.all().order("__key__")
    graph = nodes.filter("computationid =", computationid)
    if bookmark:
      logging.debug("This is a continuation.")
      logging.debug("The last batch left off with %s." % bookmark)
      next_nodes = graph.filter('__key__ >=', db.Key(bookmark))
      batch_of_nodes = next_nodes.fetch(PAGESIZE+1)
    else:
      logging.debug("This is the first batch.")
      batch_of_nodes = graph.fetch(PAGESIZE+1)

      # Count Ranks
      body = '<form action="/count-ranks" method="POST">'
      body += '<input type="hidden" name="computationid" value="'
      body += str(computationid) + '" />'
      body += '<input type="submit" value="Count" /></form>'
      self.response.out.write("<html><body>%s</body></html>" % body)
    
    logging.debug("This batch has %i nodes." % len(batch_of_nodes))
    
    logging.debug("Now I'll initialize some ranks.")
    for node in batch_of_nodes[:PAGESIZE]:
      logging.debug("I'm going to init ranks from node %s." % str(node.key()))
      ranks = DocumentRank.all().filter("computationid =", computationid)
      rank = ranks.filter("docid =", db.ByteString(node.docid)).get()
      if rank is None:
        logging.debug("This node does not have a rank.")
        rank = DocumentRank(computationid=computationid, docid=node.docid)
      if rank.dangling is True:
        logging.debug("This node is incorrectly denoted as a dangling node.")
        rank.dangling = False
        rank.put()
      outlinks = len(node.links) / 4
      logging.debug("Now I'll add ranks for the %i attached nodes." % outlinks)
      for i in range(outlinks):
        docid = key_name_from_checksum(node.links[i*4:(i+1)*4])
        task = taskqueue.Task(
          url='/init-rank',
          params={
            'computationid': str(computationid),
            'docid': docid,
          }
        )
        task.add(queue_name='parse')

    if len(batch_of_nodes) == PAGESIZE+1:
      logging.debug("There are enough nodes for another batch.")
      next = batch_of_nodes[-1]
      logging.debug("The next batch starts with node %s." % str(next.key()))
      task = taskqueue.Task(
        url='/init-ranks',
        params={
          'computationid': str(computationid),
          'node_key': str(next.key()),
        }
      )
      task.add(queue_name='parse')


def main():
  logging.getLogger().setLevel(logging.DEBUG)
  wsgiref.handlers.CGIHandler().run(webapp.WSGIApplication([
    ('/init-ranks', RankInitializer),
  ]))


if __name__ == '__main__':
  main()
